package main

import (
	"context"
	"furniture-server-gin/api/pkg/application/permission"
	"furniture-server-gin/api/pkg/application/role"
	"furniture-server-gin/api/pkg/application/user"
	"furniture-server-gin/api/pkg/infrastructure/config"
	"furniture-server-gin/api/pkg/infrastructure/repository"
	httpInterface "furniture-server-gin/api/pkg/interfaces/http"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/gin-gonic/gin"
)

func main() {
	// 初始化配置
	if err := initConfig(); err != nil {
		log.Fatalf("Failed to initialize config: %v", err)
	}

	// 初始化数据库
	mongoClient := config.GetMongoClient()
	if mongoClient == nil {
		log.Fatal("MongoDB client is not initialized")
	}

	// 创建仓库
	userRepo := repository.NewUserRepository(mongoClient.Database("furniture"))
	roleRepo := repository.NewRoleRepository(mongoClient.Database("furniture"))
	permissionRepo := repository.NewPermissionRepository(mongoClient.Database("furniture"))

	// 创建应用服务
	userService := user.NewService(userRepo)
	roleService := role.NewService(roleRepo)
	permissionService := permission.NewService(permissionRepo)

	// 创建路由
	router := setupRouter(userService, roleService, permissionService)

	// 启动服务器
	server := &http.Server{
		Addr:    ":8080",
		Handler: router,
	}

	// 在goroutine中启动服务器
	go func() {
		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("Failed to start server: %v", err)
		}
	}()

	log.Println("Server started on :8080")

	// 等待中断信号以优雅地关闭服务器
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	log.Println("Shutting down server...")

	// 优雅地关闭服务器
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := server.Shutdown(ctx); err != nil {
		log.Fatalf("Server forced to shutdown: %v", err)
	}

	// 关闭数据库连接
	if err := config.CloseMongoDB(); err != nil {
		log.Printf("Error closing MongoDB: %v", err)
	}

	log.Println("Server exiting")
}

// initConfig 初始化配置
func initConfig() error {
	// 初始化MongoDB
	mongoURI := getEnv("MONGO_URI", "mongodb://localhost:27017")
	if err := config.InitMongoDB(mongoURI); err != nil {
		return err
	}

	// 初始化Casbin
	if err := config.InitCasbin(); err != nil {
		return err
	}

	return nil
}

// setupRouter 设置路由
func setupRouter(userService *user.Service, roleService *role.Service, permissionService *permission.Service) *gin.Engine {
	router := gin.Default()

	// 创建控制器
	userController := httpInterface.NewUserController(userService)
	roleController := httpInterface.NewRoleController(roleService)
	permissionController := httpInterface.NewPermissionController(permissionService)

	// 公开路由
	public := router.Group("/api/v1")
	{
		public.POST("/register", userController.RegisterUser)
		public.POST("/login", userController.LoginUser)
	}

	// 受保护的路由
	protected := router.Group("/api/v1")
	protected.Use(httpInterface.JWTAuthMiddleware())
	{
		// 用户路由
		users := protected.Group("/users")
		{
			users.GET("/", userController.GetUsers)
			users.GET("/:id", userController.GetUser)
		}

		// 角色路由
		roles := protected.Group("/roles")
		{
			roles.POST("/", roleController.CreateRole)
			roles.GET("/", roleController.GetRoles)
			roles.GET("/:id", roleController.GetRole)
		}

		// 权限路由
		permissions := protected.Group("/permissions")
		{
			permissions.POST("/", permissionController.CreatePermission)
			permissions.GET("/", permissionController.GetPermissions)
			permissions.GET("/:id", permissionController.GetPermission)
		}
	}

	return router
}

// getEnv 获取环境变量，如果不存在则返回默认值
func getEnv(key, defaultValue string) string {
	if value := os.Getenv(key); value != "" {
		return value
	}
	return defaultValue
}
